package com.polaris.live.utils

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.LayoutInflater
import android.view.View
import android.view.animation.DecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.doOnLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.bumptech.glide.Glide
import com.polaris.live.common.ext.autoDp
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.databinding.WidgetTaskPrizeBinding
import com.polaris.live.resp.back_resp.UserTaskReward
import com.polaris.live.utils.image.ImageUtils
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 任务奖品获得动画
 * @author Created by 天晴 on 2024/10/29 9:40
 * @since 1.0.0
 **/
class TaskPrizeAnimationProxy(val viewGroup: ConstraintLayout, lifecycleOwner: LifecycleOwner) {

    init {
        lifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    viewGroup.removeAllViews()
                }
            }
        })
    }


    fun setData(rewards: List<UserTaskReward>) {
        if (rewards.isNotEmpty()) {
            viewGroup.removeAllViews()
            CoroutineScopeManager.ioScope.launch {
                rewards.forEach { da ->
                    withContext(CoroutineScopeManager.mainDispatcher) {
                        addItemView(da)
                    }
                    delay(300)
                }
            }

        }
    }

    private fun addItemView(data: UserTaskReward) {
        val mBinding = WidgetTaskPrizeBinding.inflate(LayoutInflater.from(viewGroup.context), null, false)
        mBinding.apply {
            Glide.with(viewGroup.context)
                .load(ImageUtils.imgPath(data.icon))
                .into(image)
            tvName.text = data.text
        }
        addPrizeAnimationFromBottom(mBinding.root, 200.autoDp.toFloat())
    }


    private fun animatePrizeFromBottom(view: View, targetY: Float, duration: Long = 500L) {
        val h = viewGroup.height * 0.77f
        view.translationY = h
        view.translationX = (viewGroup.width - view.width) / 2f
        val translationYAnimator = ObjectAnimator.ofFloat(view, "translationY", view.translationY - targetY).apply {
            this.duration = duration
            interpolator = DecelerateInterpolator()
        }
        var lastIndex = 0f
        translationYAnimator.addUpdateListener {
            val progress = it.animatedValue as Float

            if (progress - (h - targetY) < view.height) {
                if (lastIndex != 0f) {
                    val lastChildIndex = viewGroup.childCount - 2
                    if (lastChildIndex >= 0) {
                        for (i in 0..lastChildIndex) {
                            val previousView = viewGroup.getChildAt(i)
                            previousView.translationY = previousView.translationY - (lastIndex - progress)

                        }

                    }
                }
                lastIndex = progress
            }
        }
        val mAnimatorSet = AnimatorSet().apply {
            playSequentially(translationYAnimator)
        }


        val fadeOutAnimator = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f).apply {
            this.duration = 300L
            startDelay = duration
        }
        val mAnimatorSet1 = AnimatorSet().apply {
            playSequentially(fadeOutAnimator)
            startDelay = 1000
        }
        mAnimatorSet1.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                super.onAnimationEnd(animation)
                viewGroup.post {
                    viewGroup.removeView(view)
                }
            }
        })

        // 将两组动画结合起来
        val combinedAnimatorSet = AnimatorSet()
        combinedAnimatorSet.playSequentially(mAnimatorSet, mAnimatorSet1)
        combinedAnimatorSet.start()
    }

    private fun addPrizeAnimationFromBottom(view: View, distance: Float) {
        viewGroup.addView(view)
        view.doOnLayout {
            animatePrizeFromBottom(view, distance)
        }
    }


}